#include <cstdio>
#include <cstdlib>
#include <thread>
#include <chrono>
#include <string>
#include "zRtspClientApis.h"
#include "cpputility.h"
#ifdef WIN32
#include <Windows.h>
#else
#include <unistd.h>
#endif

void av_msleep(int ms)
{
#if defined(WIN32)
	Sleep(ms);
#else
	usleep(ms * 1000);
#endif
}
FILE *fp;
FILE *fp1;
FILE *fp2;
FILE *fp3;
FILE *fp4;
FILE *fp5;
FILE *fp6;
FILE *fp7;
FILE *fp8;
FILE *fp9;
FILE *fp10;
FILE *fp11;
FILE *fp12;
FILE *fp13;


char* d0 = "192.168.1.115/c=0&s=0";
char* d1 = "rtsp://192.168.1.115/c=0&s=0";
char* d2 = "rtsp://192.168.1.115:1554/c=0&s=0";

char* d3 = "rtsp://192.168.1.100:554/StreamType=REALTIME?ResType=IV?ResIdx=0?Audio=1";


int ParseRtspUrl(const char* url)
{
	const char* pos = strstr(url, "rtsp://");
	if (nullptr == pos) { return -1; }
	
	pos += 7;
	const char *posPort = strchr(pos, ':');
	char ipAddr[20] = { 0 };
	int port = 554;
	if (nullptr != posPort && posPort - pos < 16) {
		const char* posPortEnd = strchr(posPort, '/');
		if (posPortEnd) {
			char szTmpPort[8] = { 0 };
			memcpy(ipAddr, pos, posPort - pos);
			memcpy(szTmpPort, posPort + 1, posPortEnd - posPort-1);
			port = atoi(szTmpPort);
		}
	} else {
		const char* posIpEnd = strchr(pos, '/');
		if (posIpEnd) {
			memcpy(ipAddr, pos, posIpEnd - pos);
		}

	}
	av_msg("ip.addr %s, port %d\n", ipAddr, port);
}


int ZRtspFrameCallBack(int handle, int frameType, ZRtspFrameInfo* info)
{
	if (ZRC_FRAME_TYPE_VIDEO != frameType) return 0;
	char head[4] = {0};
	head[0] = 0x00; head[1] = 0x00; head[2] = 0x00; head[3] = 0x01;
	double ts = info->presentationTime.tv_sec + double(info->presentationTime.tv_usec) / 1000000;
	//av_msg("handle %d, frameType %d, codec %d, buffLen %d, TS %lf [%02X %02X] %d\n",
	//	handle, frameType, info->codec, info->frameLen, ts,
	//	info->pBuffer[0], info->pBuffer[1], (info->pBuffer[0] & 0x1F));
	fwrite(head, 4, 1, fp);
	fwrite(info->pBuffer, info->frameLen, 1, fp);

	
	return 0;
}

int ZRtspFrameCallBack1(int handle, int frameType, ZRtspFrameInfo* info)
{
	if (ZRC_FRAME_TYPE_VIDEO != frameType) return 0;
	char head[4] = {0};
	head[0] = 0x00; head[1] = 0x00; head[2] = 0x00; head[3] = 0x01;
	double ts = info->presentationTime.tv_sec + double(info->presentationTime.tv_usec) / 1000000;
	//av_msg("handle %d, frameType %d, codec %d, buffLen %d, TS %lf [%02X %02X] %d\n",
	//	handle, frameType, info->codec, info->frameLen, ts,
	//	info->pBuffer[0], info->pBuffer[1], (info->pBuffer[0] & 0x1F));
	fwrite(head, 4, 1, fp1);
	fwrite(info->pBuffer, info->frameLen, 1, fp1);
	return 0;
}

int ZRtspFrameCallBack2(int handle, int frameType, ZRtspFrameInfo* info)
{
	if (ZRC_FRAME_TYPE_VIDEO != frameType) return 0;
	char head[4] = {0};
	head[0] = 0x00; head[1] = 0x00; head[2] = 0x00; head[3] = 0x01;
	double ts = info->presentationTime.tv_sec + double(info->presentationTime.tv_usec) / 1000000;
	//av_msg("handle %d, frameType %d, codec %d, buffLen %d, TS %lf [%02X %02X] %d\n",
	//	handle, frameType, info->codec, info->frameLen, ts,
	//	info->pBuffer[0], info->pBuffer[1], (info->pBuffer[0] & 0x1F));
	fwrite(head, 4, 1, fp2);
	fwrite(info->pBuffer, info->frameLen, 1, fp2);
	return 0;
}

int ZRtspFrameCallBack3(int handle, int frameType, ZRtspFrameInfo* info)
{
	if (ZRC_FRAME_TYPE_VIDEO != frameType) return 0;
	char head[4] = {0};
	head[0] = 0x00; head[1] = 0x00; head[2] = 0x00; head[3] = 0x01;
	double ts = info->presentationTime.tv_sec + double(info->presentationTime.tv_usec) / 1000000;
	//av_msg("handle %d, frameType %d, codec %d, buffLen %d, TS %lf [%02X %02X] %d\n",
	//	handle, frameType, info->codec, info->frameLen, ts,
	//	info->pBuffer[0], info->pBuffer[1], (info->pBuffer[0] & 0x1F));
	fwrite(head, 4, 1, fp3);
	fwrite(info->pBuffer, info->frameLen, 1, fp3);
	return 0;
}

int ZRtspFrameCallBack4(int handle, int frameType, ZRtspFrameInfo* info)
{
	if (ZRC_FRAME_TYPE_VIDEO != frameType) return 0;
	char head[4] = {0};
	head[0] = 0x00; head[1] = 0x00; head[2] = 0x00; head[3] = 0x01;
	double ts = info->presentationTime.tv_sec + double(info->presentationTime.tv_usec) / 1000000;
	//av_msg("handle %d, frameType %d, codec %d, buffLen %d, TS %lf [%02X %02X] %d\n",
	//	handle, frameType, info->codec, info->frameLen, ts,
	//	info->pBuffer[0], info->pBuffer[1], (info->pBuffer[0] & 0x1F));
	fwrite(head, 4, 1, fp4);
	fwrite(info->pBuffer, info->frameLen, 1, fp4);
	return 0;
}

int ZRtspFrameCallBack5(int handle, int frameType, ZRtspFrameInfo* info)
{
	if (ZRC_FRAME_TYPE_VIDEO != frameType) return 0;
	char head[4] = {0};
	head[0] = 0x00; head[1] = 0x00; head[2] = 0x00; head[3] = 0x01;
	double ts = info->presentationTime.tv_sec + double(info->presentationTime.tv_usec) / 1000000;
	//av_msg("handle %d, frameType %d, codec %d, buffLen %d, TS %lf [%02X %02X] %d\n",
	//	handle, frameType, info->codec, info->frameLen, ts,
	//	info->pBuffer[0], info->pBuffer[1], (info->pBuffer[0] & 0x1F));
	fwrite(head, 4, 1, fp5);
	fwrite(info->pBuffer, info->frameLen, 1, fp5);
	return 0;
}

int ZRtspFrameCallBack6(int handle, int frameType, ZRtspFrameInfo* info)
{
	if (ZRC_FRAME_TYPE_VIDEO != frameType) return 0;
	char head[4] = {0};
	head[0] = 0x00; head[1] = 0x00; head[2] = 0x00; head[3] = 0x01;
	double ts = info->presentationTime.tv_sec + double(info->presentationTime.tv_usec) / 1000000;
//	av_msg("handle %d, frameType %d, codec %d, buffLen %d, TS %lf [%02X %02X] %d\n",
//		handle, frameType, info->codec, info->frameLen, ts,
//		info->pBuffer[0], info->pBuffer[1], (info->pBuffer[0] & 0x1F));
	fwrite(head, 4, 1, fp6);
	fwrite(info->pBuffer, info->frameLen, 1, fp6);
	return 0;
}

int ZRtspFrameCallBack7(int handle, int frameType, ZRtspFrameInfo* info)
{
	if (ZRC_FRAME_TYPE_VIDEO != frameType) return 0;
	char head[4] = {0};
	head[0] = 0x00; head[1] = 0x00; head[2] = 0x00; head[3] = 0x01;
	double ts = info->presentationTime.tv_sec + double(info->presentationTime.tv_usec) / 1000000;
//	av_msg("handle %d, frameType %d, codec %d, buffLen %d, TS %lf [%02X %02X] %d\n",
//		handle, frameType, info->codec, info->frameLen, ts,
//		info->pBuffer[0], info->pBuffer[1], (info->pBuffer[0] & 0x1F));
	fwrite(head, 4, 1, fp7);
	fwrite(info->pBuffer, info->frameLen, 1, fp7);
	return 0;
}

int ZRtspFrameCallBack8(int handle, int frameType, ZRtspFrameInfo* info)
{
	if (ZRC_FRAME_TYPE_VIDEO != frameType) return 0;
	char head[4] = {0};
	head[0] = 0x00; head[1] = 0x00; head[2] = 0x00; head[3] = 0x01;
	double ts = info->presentationTime.tv_sec + double(info->presentationTime.tv_usec) / 1000000;
//	av_msg("handle %d, frameType %d, codec %d, buffLen %d, TS %lf [%02X %02X] %d\n",
//		handle, frameType, info->codec, info->frameLen, ts,
//		info->pBuffer[0], info->pBuffer[1], (info->pBuffer[0] & 0x1F));
	fwrite(head, 4, 1, fp8);
	fwrite(info->pBuffer, info->frameLen, 1, fp8);
	return 0;
}

int ZRtspFrameCallBack9(int handle, int frameType, ZRtspFrameInfo* info)
{
	if (ZRC_FRAME_TYPE_VIDEO != frameType) return 0;
	char head[4] = {0};
	head[0] = 0x00; head[1] = 0x00; head[2] = 0x00; head[3] = 0x01;
	double ts = info->presentationTime.tv_sec + double(info->presentationTime.tv_usec) / 1000000;
//	av_msg("handle %d, frameType %d, codec %d, buffLen %d, TS %lf [%02X %02X] %d\n",
//		handle, frameType, info->codec, info->frameLen, ts,
//		info->pBuffer[0], info->pBuffer[1], (info->pBuffer[0] & 0x1F));
	fwrite(head, 4, 1, fp9);
	fwrite(info->pBuffer, info->frameLen, 1, fp9);
	return 0;
}

int ZRtspFrameCallBack10(int handle, int frameType, ZRtspFrameInfo* info)
{
	if (ZRC_FRAME_TYPE_VIDEO != frameType) return 0;
	char head[4] = {0};
	head[0] = 0x00; head[1] = 0x00; head[2] = 0x00; head[3] = 0x01;
	double ts = info->presentationTime.tv_sec + double(info->presentationTime.tv_usec) / 1000000;
//	av_msg("handle %d, frameType %d, codec %d, buffLen %d, TS %lf [%02X %02X] %d\n",
//		handle, frameType, info->codec, info->frameLen, ts,
//		info->pBuffer[0], info->pBuffer[1], (info->pBuffer[0] & 0x1F));
	fwrite(head, 4, 1, fp10);
	fwrite(info->pBuffer, info->frameLen, 1, fp10);
	return 0;
}

int ZRtspFrameCallBack11(int handle, int frameType, ZRtspFrameInfo* info)
{
	if (ZRC_FRAME_TYPE_VIDEO != frameType) return 0;
	char head[4] = {0};
	head[0] = 0x00; head[1] = 0x00; head[2] = 0x00; head[3] = 0x01;
	double ts = info->presentationTime.tv_sec + double(info->presentationTime.tv_usec) / 1000000;
//	av_msg("handle %d, frameType %d, codec %d, buffLen %d, TS %lf [%02X %02X] %d\n",
//		handle, frameType, info->codec, info->frameLen, ts,
//		info->pBuffer[0], info->pBuffer[1], (info->pBuffer[0] & 0x1F));
	fwrite(head, 4, 1, fp11);
	fwrite(info->pBuffer, info->frameLen, 1, fp11);
	return 0;
}

int ZRtspFrameCallBack12(int handle, int frameType, ZRtspFrameInfo* info)
{
	if (ZRC_FRAME_TYPE_VIDEO != frameType) return 0;
	char head[4] = {0};
	head[0] = 0x00; head[1] = 0x00; head[2] = 0x00; head[3] = 0x01;
	double ts = info->presentationTime.tv_sec + double(info->presentationTime.tv_usec) / 1000000;
	av_msg("handle %d, frameType %d, codec %d, buffLen %d, TS %lf [%02X %02X] %d\n",
		handle, frameType, info->codec, info->frameLen, ts,
		info->pBuffer[0], info->pBuffer[1], (info->pBuffer[0] & 0x1F));
	fwrite(head, 4, 1, fp12);
	fwrite(info->pBuffer, info->frameLen, 1, fp12);
	return 0;
}

int ZRtspFrameCallBack13(int handle, int frameType, ZRtspFrameInfo* info)
{
	if (ZRC_FRAME_TYPE_VIDEO != frameType) return 0;
	char head[4] = {0};
	head[0] = 0x00; head[1] = 0x00; head[2] = 0x00; head[3] = 0x01;
	double ts = info->presentationTime.tv_sec + double(info->presentationTime.tv_usec) / 1000000;
	av_msg("handle %d, frameType %d, codec %d, buffLen %d, TS %lf [%02X %02X] %d\n",
		handle, frameType, info->codec, info->frameLen, ts,
		info->pBuffer[0], info->pBuffer[1], (info->pBuffer[0] & 0x1F));
	fwrite(head, 4, 1, fp13);
	fwrite(info->pBuffer, info->frameLen, 1, fp13);
	return 0;
}

int main(int argc, char* argv[])
{
	//ParseRtspUrl(d0);
	//ParseRtspUrl(d1);
	//ParseRtspUrl(d2);
	//ParseRtspUrl(d3);
	//return 0;
	fp  = fopen((char *)"./Out/0.264", "w+");
	fp1 = fopen((char *)"./Out/1.264", "w+");
	fp2 = fopen((char *)"./Out/2.264", "w+");
	fp3 = fopen((char *)"./Out/3.264", "w+");
	fp4 = fopen((char *)"./Out/4.264", "w+");
	fp5 = fopen((char *)"./Out/5.264", "w+");
	fp6 = fopen((char *)"./Out/6.264", "w+");
	fp7 = fopen((char *)"./Out/7.264", "w+");
	fp8 = fopen((char *)"./Out/8.264", "w+");
	fp9 = fopen((char *)"./Out/9.264", "w+");
	fp10= fopen((char *)"./Out/10.264","w+");
	fp11= fopen((char *)"./Out/11.264","w+");
	ZRtspClientInit();
	int r;
	
	r = ZRtspClientOpenStream((char *)"rtsp://admin:gaozhi2014@10.67.0.99:554/Streaming/Channels/101?", ZRtspFrameCallBack, ZRC_RTP_CONNECT_TYPE_TCP, "", "", 1*1024*1024);
	r = ZRtspClientOpenStream("rtsp://admin:gaozhi2014@10.67.0.99:554/Streaming/Channels/101?", ZRtspFrameCallBack1, ZRC_RTP_CONNECT_TYPE_TCP, "", "", 1*1024*1024);
	r = ZRtspClientOpenStream("rtsp://admin:gaozhi2014@10.67.0.99:554/Streaming/Channels/101?", ZRtspFrameCallBack2, ZRC_RTP_CONNECT_TYPE_TCP, "", "", 1*1024*1024);
	r = ZRtspClientOpenStream("rtsp://10.67.0.65:554/12", ZRtspFrameCallBack3, ZRC_RTP_CONNECT_TYPE_TCP, "", "", 1*1024*1024);
	r = ZRtspClientOpenStream("rtsp://10.67.0.70:554/11", ZRtspFrameCallBack4, ZRC_RTP_CONNECT_TYPE_TCP, "", "", 1*1024*1024);
	r = ZRtspClientOpenStream("rtsp://admin:gaozhi2014@10.67.0.99:554/Streaming/Channels/101?", ZRtspFrameCallBack5, ZRC_RTP_CONNECT_TYPE_TCP, "", "", 1*1024*1024);
	r = ZRtspClientOpenStream("rtsp://admin:gaozhi2014@10.67.0.99:554/Streaming/Channels/102?", ZRtspFrameCallBack6, ZRC_RTP_CONNECT_TYPE_TCP, "", "", 1*1024*1024);
	r = ZRtspClientOpenStream("rtsp://admin:gaozhi2014@10.67.0.99:554/Streaming/Channels/101?", ZRtspFrameCallBack7, ZRC_RTP_CONNECT_TYPE_TCP, "", "", 1*1024*1024);
	r = ZRtspClientOpenStream("rtsp://admin:gaozhi2014@10.67.0.99:554/Streaming/Channels/102?", ZRtspFrameCallBack8, ZRC_RTP_CONNECT_TYPE_TCP, "", "", 1*1024*1024);
	r = ZRtspClientOpenStream("rtsp://admin:gaozhi2014@10.67.0.99:554/Streaming/Channels/102?", ZRtspFrameCallBack9, ZRC_RTP_CONNECT_TYPE_TCP, "", "", 1*1024*1024);
	r = ZRtspClientOpenStream("rtsp://admin:gaozhi2014@10.67.0.99:554/Streaming/Channels/102?", ZRtspFrameCallBack10, ZRC_RTP_CONNECT_TYPE_TCP, "", "", 1*1024*1024);
	r = ZRtspClientOpenStream("rtsp://admin:gaozhi2014@10.67.0.99:554/Streaming/Channels/102?", ZRtspFrameCallBack11, ZRC_RTP_CONNECT_TYPE_TCP, "", "", 1*1024*1024);
	//r = ZRtspClientOpenStream("rtsp://admin:gaozhi2014@10.67.0.99:554/Streaming/Channels/102?", ZRtspFrameCallBack12, ZRC_RTP_CONNECT_TYPE_TCP, "", "", 1*1024*1024);
	//r = ZRtspClientOpenStream("rtsp://10.67.1.57/11", ZRtspFrameCallBack5, ZRC_RTP_CONNECT_TYPE_TCP, "", "", 350*1024);
	//r = ZRtspClientOpenStream("rtsp://10.67.1.57/11", ZRtspFrameCallBack6, ZRC_RTP_CONNECT_TYPE_TCP, "", "", 350*1024);
	//r = ZRtspClientOpenStream("rtsp://10.67.1.57/11", ZRtspFrameCallBack7, ZRC_RTP_CONNECT_TYPE_TCP, "", "", 350*1024);
	//r = ZRtspClientOpenStream("rtsp://10.67.1.57/11", ZRtspFrameCallBack8, ZRC_RTP_CONNECT_TYPE_TCP, "", "", 350*1024);
	//r = ZRtspClientOpenStream("rtsp://10.67.1.57/11", ZRtspFrameCallBack9, ZRC_RTP_CONNECT_TYPE_TCP, "", "", 350*1024);
	//r = ZRtspClientOpenStream("rtsp://10.67.1.57/11", ZRtspFrameCallBack10, ZRC_RTP_CONNECT_TYPE_TCP, "", "", 350*1024);	
	av_msg("========================================= handle %d\n", r);
	//r = ZRtspClientOpenStream("rtsp://192.168.1.115/c=0&s=1", ZRtspFrameCallBack, ZRC_RTP_CONNECT_TYPE_TCP, "", "", 350 * 1024);
	//av_msg("========================================= handle %d\n", r);

	//r = ZRtspClientOpenStream("rtsp://192.168.1.115/c=0&s=0", ZRC_RTP_CONNECT_TYPE_TCP, "", "");
	//r = ZRtspClientOpenStream("rtsp://192.168.1.115/c=0&s=1", ZRC_RTP_CONNECT_TYPE_TCP, "", "");
	
	//r = ZRtspClientOpenStream("rtsp://192.168.1.100:554/StreamType=REALTIME?ResType=IV?ResIdx=0?Audio=1", ZRC_RTP_CONNECT_TYPE_TCP, "", "");
		
	//while (1) {
	//	int c1 = ZRtspClientOpenStream("rtsp://192.168.1.69/c=0&s=1",ZRtspFrameCallBack, ZRC_RTP_CONNECT_TYPE_TCP, "", "", 350*1024);
	//	av_msg("c1 ========================================= handle %d\n", c1);
	//	av_msleep(1000 * 5);
	//	ZRtspClientCloseStream(c1);
	//	av_msleep(1000 * 1);
	//}

	//int c1 = 10, c2 = 20;
	//while (1) {
	//	av_msleep(1000 * 2);
	//	ZRtspClientCloseStream(c2);
	//	c1 = ZRtspClientOpenStream("rtsp://192.168.1.69/c=0&s=1",ZRtspFrameCallBack, ZRC_RTP_CONNECT_TYPE_TCP, "", "");
	//	av_msg("c1 ========================================= handle %d\n", c1);
	//	av_msleep(1000 * 5);
	//	av_msg("close stream handle %d\n", r);
	//	c2 = ZRtspClientOpenStream("rtsp://192.168.1.69/c=0&s=0",ZRtspFrameCallBack, ZRC_RTP_CONNECT_TYPE_TCP, "", "");
	//	av_msg("c2 ####################################### handle %d\n", c2);
	//	ZRtspClientCloseStream(c1);
	//}
	while (1) { av_msleep(1000 * 1000); }
	fclose(fp);
	return 0;
}


//

